//
//  SUPlayer.m
//  SUMusic
//
//  Created by KevinSu on 16/1/10.
//  Copyright © 2016年 KevinSu. All rights reserved.
//

#import "SUPlayerManager.h"

#import "JPAudioMainVC.h"
#import "SURateAlertVC.h"

@interface SUPlayerManager()
@property (nonatomic,strong) UIImageView *iconImage;
@property (nonatomic,assign) BOOL isCommonSong;
@property (nonatomic,assign) BOOL isCommonIdex;
@end

@implementation SUPlayerManager
{
    NSTimer *_timer;
    NSInteger _count;
    
    NSTimer *_learnTimer; // 学习时长
    
    float _total;
}

+ (instancetype)manager {
    
    static SUPlayerManager * player;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        player = [[SUPlayerManager alloc]init];
        player.mode = SUModeOrder;
        player.saveClock = @"不开启";
        player.accumulateCount = 0;
    });
    return player;
}


- (void)setSaveClock:(NSString *)saveClock
{
    _saveClock = saveClock;
    
    [_timer invalidate];
    _timer = nil;
    if ([saveClock isEqualToString:@"播完当前媒体再关闭"] || [saveClock isEqualToString:@"不开启"]) {
        return;
    }
    
//    [_timer setFireDate:[NSDate distantFuture]];
    _timer = [NSTimer scheduledTimerWithTimeInterval:1 target:self selector:@selector(countDownSet) userInfo:nil repeats:YES];

    if ([saveClock isEqualToString:@"10分钟后"]) {
        _count = 10*60;
//        _count = 10;
    } else if ([saveClock isEqualToString:@"20分钟后"]) {
        _count = 20*60;
    } else if ([saveClock isEqualToString:@"30分钟后"]) {
        _count = 30*60;
    } else if ([saveClock isEqualToString:@"60分钟后"]) {
        _count = 60*60;
    } else if ([saveClock isEqualToString:@"90分钟后"]) {
        _count = 90*60;
    }
}

- (void)countDownSet
{
    _count--;
    if (_count <= 0) {
        [_timer setFireDate:[NSDate distantFuture]];
        [self pausePlay];
        self.saveClock = @"不开启";
    }
    
    self.clockLeft = _count;
    
    NSLog(@"倒计时 %ld", _count);
}

- (void)setCurrentSong:(NSDictionary *)currentSong {
    if ([_currentSong isEqualToDictionary:currentSong]) {
        self.isCommonSong = true;
    }
    _currentSong = currentSong;
}

- (void)setCurrentSongIndex:(NSInteger)currentSongIndex {
    if (_currentSongIndex == currentSongIndex) {
        self.isCommonIdex = true;
    }
    _currentSongIndex = currentSongIndex;
}

- (void)setSongList:(NSMutableArray<NSDictionary *> *)songList
{
    if (self.isCommonIdex == true) {
        if ([_songList isEqualToArray:songList]) {
            self.isCommonIdex = false;
            return;;
        }
    }
    
    _songList = songList;
    if (self.isCommonSong == true) {
        self.isCommonSong = false;
        return;
    }
    
    
    
    [self.downloadTask cancel];
    
    [self endPlay];
    [self loadSongInfoWithNewList];
    [self startPlay];
    
    [self updateBottomView];
}

- (void)updateBottomView
{
    self.bottomView.classLabel.text = [NSString stringWithFormat:@"%@|%@", self.currentSong[@"top_pid_name"], self.currentSong[@"media_class_name"]];
    [self.bottomView.imgView sd_setImageWithURL:[NSURL URLWithString:self.currentSong[@"image"]] placeholderImage:[UIImage imageNamed:@"Logo"]];

    self.bottomView.nameLabel.text = self.currentSong[@"name"];
    if (self.status == SUPlayStatusPlay) {
        self.bottomView.statusImg.image = [UIImage imageNamed:@"narrow_playBtn_play"];
        [self.bottomView startAnimating];
    } else {
        self.bottomView.statusImg.image = [UIImage imageNamed:@"narrow_playBtn_puse"];
        [self.bottomView stopAnimating];
    }
    
    [[NSNotificationCenter defaultCenter] postNotificationName:kUpdateCurrentPlayUI object:self.currentSong];
}

#pragma mark - 播放器
/*
 * 播放器播放状态
 */
- (BOOL)isPlaying {
    return self.player.rate == 1;
}


/*
 * 总时长(秒)
 */
- (void)setPlayDuration:(NSString *)playDuration {
    if (![_playDuration isEqualToString:playDuration] &&
        ![playDuration isEqualToString:@"0"]) {
        _playDuration = playDuration;
    }else {
        _playDuration = playDuration;
    }
}

/*
 * 当前播放时间(00:00)
 */
- (NSString *)timeNow {
    
    return [NSString convertStringWithTime:self.playTime.floatValue];
}

/*
 * 总时长(00:00)
 */
- (NSString *)duration {
    
    return [NSString convertStringWithTime:self.playDuration.floatValue];
}




/*
 * 开始播放
 */
- (void)startPlay {
    self.status = SUPlayStatusPlay;
    self.bottomView.statusImg.image = [UIImage imageNamed:@"narrow_playBtn_play"];
    [self.player play];
    
    if (self.saveRate) {
        self.player.rate = self.saveRate;
    } else {
        self.saveRate = self.player.rate;
    }
    
    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1.5 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
        [self setLockingInfo];
    });
   
}

- (void)setLockingInfo {
    NSDictionary *current = self.currentSong;
    if (current == nil) { return ;}
    NSMutableDictionary *dict = [[NSMutableDictionary alloc] init];
    
    //设置歌曲题目
    if (current[@"media_class_name"] != nil) {
        [dict setObject:current[@"media_class_name"] forKey:MPMediaItemPropertyTitle];
    }
    
    //设置歌手名
    if (current[@"name"] != nil){
        [dict setObject:current[@"name"] forKey:MPMediaItemPropertyArtist];
}
    //设置专辑名
    
//    [dict setObject:@"专辑" forKey:MPMediaItemPropertyAlbumTitle];
    
    //设置显示的图片
    NSString *imagePath = self.currentSong[@"image"] ?: @"";
    if (imagePath) {
        [self.iconImage sd_setImageWithURL:[NSURL URLWithString:imagePath] completed:^(UIImage * _Nullable image, NSError * _Nullable error, SDImageCacheType cacheType, NSURL * _Nullable imageURL) {
            
            
            if (image != nil) {
                [dict setObject:[[MPMediaItemArtwork alloc] initWithImage:image] forKey:MPMediaItemPropertyArtwork];
            } else {
                UIImage *newImage = [UIImage imageNamed:@"Logo"];
                [dict setObject:[[MPMediaItemArtwork alloc] initWithImage:newImage] forKey:MPMediaItemPropertyArtwork];
            }
            //设置歌曲时长
            [dict setObject:[NSNumber numberWithDouble:self.playDuration.floatValue] forKey:MPMediaItemPropertyPlaybackDuration];
            
            //设置已经播放时长
            [dict setObject:[NSNumber numberWithDouble:self.playTime.floatValue] forKey:MPNowPlayingInfoPropertyElapsedPlaybackTime];
            
            //更新字典
            [[MPNowPlayingInfoCenter defaultCenter] setNowPlayingInfo:dict];
        }];
    } else {
        UIImage *newImage = [UIImage imageNamed:@"Logo"];
        NSLog(@"%@",newImage.size);
        [dict setObject:[[MPMediaItemArtwork alloc] initWithImage:newImage] forKey:MPMediaItemPropertyArtwork];
        //设置歌曲时长
        [dict setObject:[NSNumber numberWithDouble:self.playDuration.floatValue] forKey:MPMediaItemPropertyPlaybackDuration];
        
        //设置已经播放时长
        [dict setObject:[NSNumber numberWithDouble:self.playTime.floatValue] forKey:MPNowPlayingInfoPropertyElapsedPlaybackTime];
        
        //更新字典
        [[MPNowPlayingInfoCenter defaultCenter] setNowPlayingInfo:dict];
    }

}



/*
 * 暂停播放
 */
- (void)pausePlay {
    self.status = SUPlayStatusPause;
    self.bottomView.statusImg.image = [UIImage imageNamed:@"narrow_playBtn_puse"];
    [self.player pause];
}

/*
 * 播放完毕
 */
- (void)endPlay {
    if (self.player == nil) return;
    
    self.status = SUPlayStatusStop;
    [self.player pause];
    
    //移除监控
    [self removeObserver];
    
    //重置进度
    self.progress = 0.f;
    self.playTime = @"0";
    self.playDuration = @"0";
    
}




#pragma mark - 加载歌曲
/*
 * 加载歌曲
 * reset: 从头开始
 */
- (void)loadSongInfoWithNewList {
    
    //更新当前歌曲信息
    self.currentSong = self.songList[self.currentSongIndex];
    NSLog(@"current %@", self.currentSong);
    
    NSString *orignalUrl = self.currentSong[@"audio_url"];
    if ([orignalUrl containsString:@".mp3"]) {
        orignalUrl = [orignalUrl stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
    } else {
        orignalUrl = [[[MBGeneralManager manager] getDecryptedStringWithEncryptedString:orignalUrl] stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
    }
    NSURL * url = [NSURL URLWithString:orignalUrl];
    
    AVPlayerItem * songItem;
    
    // 判断本地有没有文件
    NSString *fullName = [NSString stringWithFormat:@"%@-%@.mp3", self.currentSong[@"id"], self.currentSong[@"name"]];
    NSString *filePath = [[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES)objectAtIndex:0]stringByAppendingPathComponent:fullName];
    NSFileManager *fileManager = [NSFileManager defaultManager];
    BOOL isExist = [fileManager fileExistsAtPath:filePath];
    if (isExist) {
        NSLog(@"存在");
        
        url = [NSURL fileURLWithPath:filePath];
        songItem = [[AVPlayerItem alloc]initWithURL:url];
    } else {
        NSLog(@"不存在");
        
        songItem = [[AVPlayerItem alloc]initWithURL:url];
        
        // 下载音频
        AVURLAsset *asset = (AVURLAsset *)songItem.asset;
        NSURL *audioURL = asset.URL;
        
        NSURLSessionConfiguration *config = [NSURLSessionConfiguration defaultSessionConfiguration];
        NSURLSession *session = [NSURLSession sessionWithConfiguration:config delegate:self delegateQueue:nil];
        self.downloadTask = [session downloadTaskWithURL:audioURL];
        [self.downloadTask resume];
    }
    
    // 创建播放器
    songItem.canUseNetworkResourcesForLiveStreamingWhilePaused = YES;
    
    if (self.player == nil) {
        self.player = [[AVPlayer alloc]initWithPlayerItem:songItem];
    }else {
        [self.player replaceCurrentItemWithPlayerItem:songItem];
    }
    [[NSNotificationCenter defaultCenter] postNotificationName:@"updatePlayItem" object:nil];
    
    //给当前歌曲添加监控
    [self addObserver];
    
    self.status = SUPlayStatusPlay;
    // 刷新控件
    [self updateBottomView];
    // 锁屏
    [[AppDelegate delegate] configNowPlayingCenter];
    
}

#pragma mark NSURLSessionDelegate
- (void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask didFinishDownloadingToURL:(NSURL *)location
{
    //下载完成后回调.  location 就是文件下载之后保存的路径
    NSArray *documentPath = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
    NSString *path = [documentPath objectAtIndex:0];

    NSString *plistPath = [path stringByAppendingPathComponent:[NSString stringWithFormat:@"%@-%@.mp3", self.currentSong[@"id"], self.currentSong[@"name"]]];

    NSFileManager *fileManager = [NSFileManager defaultManager];
    BOOL isFile = [fileManager fileExistsAtPath:plistPath];
    if (isFile) {
        [fileManager removeItemAtPath:plistPath error:nil];
    }
    BOOL success = [fileManager moveItemAtPath:location.path toPath:plistPath error:nil];
    if (success) {
        NSLog(@"下载成功");
    } else {
        NSLog(@"下载失败");
    }
}

- (void)URLSession:(NSURLSession *)session
      downloadTask:(NSURLSessionDownloadTask *)downloadTask
      didWriteData:(int64_t)bytesWritten
 totalBytesWritten:(int64_t)totalBytesWritten
totalBytesExpectedToWrite:(int64_t)totalBytesExpectedToWrite
{

//    NSLog(@"本次下载数据的长度 %lld, 已经下载 %lld, 文件的总长度 %lld", bytesWritten,totalBytesWritten,totalBytesExpectedToWrite);
}



#pragma mark - KVO
- (void)addObserver {
    
    AVPlayerItem * songItem = self.player.currentItem;
    self.saveBufferProgress = 0;
    
    //给AVPlayerItem添加播放完成通知
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(playbackFinished:) name:AVPlayerItemDidPlayToEndTimeNotification object:songItem];
    
    //更新播放器进度
    __weak typeof(self) weakSelf = self;
    _timeObserve = [self.player addPeriodicTimeObserverForInterval:CMTimeMake(1.0, 1.0) queue:dispatch_get_main_queue() usingBlock:^(CMTime time) {
        float current = CMTimeGetSeconds(time);
        float total = CMTimeGetSeconds(songItem.duration);
        //        SuLog(@"%f, %f",current, total);
        if (current) {
            weakSelf.progress = current / total;
            weakSelf.playTime = [NSString stringWithFormat:@"%.f",current];
            weakSelf.playDuration = [NSString stringWithFormat:@"%.2f",total];
        }
        
        weakSelf.accumulateCount += 1;
    }];
    
    //监控网络加载情况属性
    [songItem addObserver:self forKeyPath:@"loadedTimeRanges" options:NSKeyValueObservingOptionNew context:nil];
    //监控播放状态
    [songItem addObserver:self forKeyPath:@"status" options:NSKeyValueObservingOptionNew context:nil];
}

- (void)removeObserver {
    
    AVPlayerItem * songItem = self.player.currentItem;
    
    [[NSNotificationCenter defaultCenter] removeObserver:self];
    [songItem removeObserver:self forKeyPath:@"loadedTimeRanges"];
    [songItem removeObserver:self forKeyPath:@"status"];
    
    if (_timeObserve) {
        [self.player removeTimeObserver:_timeObserve];
        _timeObserve = nil;
    }
    
    [self.player replaceCurrentItemWithPlayerItem:nil];
}


- (void)playbackFinished:(NSNotification *)notice {
    
    if ([self.saveClock isEqualToString:@"播完当前媒体再关闭"]) {
        [self endPlay];
        return;
    }
    [self playNextSong];
    [[NSNotificationCenter defaultCenter] postNotificationName:@"autoPlay" object:nil];
}




#pragma mark - 播放器网络操作
- (void)playLastSong
{
    if (self.mode == SUModeSingle) {
        
    } else if (self.mode == SUModeOrder) {
        NSInteger result = self.currentSongIndex - 1;
        if (result<0) {
            [[NSNotificationCenter defaultCenter] postNotificationName:@"noLast" object:nil];
            return;
        }
        self.currentSongIndex -= 1;
    } else if (self.mode == SUModeRandom) {
        NSInteger index = arc4random()%self.songList.count;
        self.currentSongIndex = index;
    }
    
    
    [self endPlay];
    [self loadSongInfoWithNewList];
    [self startPlay];
}

- (void)playNextSong
{
    if (self.mode == SUModeSingle) {
        
    } else if (self.mode == SUModeOrder) {
        NSInteger result = self.currentSongIndex + 1;
        if (result>self.songList.count-1) {
            [[NSNotificationCenter defaultCenter] postNotificationName:@"noNext" object:nil];
            return;
        }
        self.currentSongIndex += 1;
    } else if (self.mode == SUModeRandom) {
        NSInteger index = arc4random()%self.songList.count;
        self.currentSongIndex = index;
    }
    
    [self endPlay];
    [self loadSongInfoWithNewList];
    [self startPlay];
}

- (void)skipSong
{
    [self endPlay];
    [self loadSongInfoWithNewList];
    [self startPlay];
}

/**
 *  通过KVO监控缓冲进度
 */
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSString *,id> *)change context:(void *)context {
    
    AVPlayerItem * songItem = object;
    if ([keyPath isEqualToString:@"loadedTimeRanges"]) {
        
        NSArray * timeRanges = self.player.currentItem.loadedTimeRanges;
        //本次缓冲的时间范围
        CMTimeRange timeRange = [timeRanges.firstObject CMTimeRangeValue];
        //缓冲总长度
        NSTimeInterval totalLoadTime = CMTimeGetSeconds(timeRange.start) + CMTimeGetSeconds(timeRange.duration);
        //音乐的总时间
        NSTimeInterval duration = CMTimeGetSeconds(self.player.currentItem.duration);
        //计算缓冲百分比例
        NSTimeInterval scale = totalLoadTime/duration;
        
        if (self.saveBufferProgress > scale) {
            self.bufferProgress = self.saveBufferProgress;
        } else {
            self.bufferProgress = scale;
            self.saveBufferProgress = self.bufferProgress;
        }
//        NSLog(@"buffer:%f  total:%f", totalLoadTime,duration);
    }else if ([keyPath isEqualToString:@"status"]) {
    
    }
}



- (float)getBufferProgress
{
    AVPlayerItem *playerItem = self.player.currentItem;
    if (playerItem.loadedTimeRanges.count > 0) {
        CMTimeRange range = [[[playerItem loadedTimeRanges] objectAtIndex:0] CMTimeRangeValue];
        double startSeconds = CMTimeGetSeconds(range.start);
        double durationSeconds = CMTimeGetSeconds(range.duration);
        double loadedTime = startSeconds + durationSeconds;
        double totalDuration = CMTimeGetSeconds([self.player.currentItem duration]);
        double progress = loadedTime / totalDuration;
        return progress;
    }
    else {
        return 0;
    }
}


- (JPHomeBottomView *)bottomView
{
    if (!_bottomView) {
        _bottomView = [[NSBundle mainBundle] loadNibNamed:@"JPHomeBottomView" owner:self options:nil].lastObject;
        [_bottomView setTapBlock:^(NSInteger index, UIImageView *img) {
            if (index == 0) {
                JPAudioMainVC *vc = [JPAudioMainVC new];
                UINavigationController *nav = [[UINavigationController alloc] initWithRootViewController:vc];
                nav.modalPresentationStyle = UIModalPresentationFullScreen;
                [[UIApplication sharedApplication].keyWindow.rootViewController presentViewController:nav animated:YES completion:nil];
            } else if (index == 1) {
                
            } else if (index == 3) { // 收缩
                
            } else {
                SURateAlertVC *vc = [SURateAlertVC new];
                [vc setChoseBlock:^(NSInteger index) {
                    [[SUPlayerManager manager] skipSong];
    //                [weakSelf refreshBTV];
                }];
                vc.tagInt = 2;
                vc.view.frame = CGRectMake(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT);
                [[UIApplication sharedApplication].windows.firstObject addSubview:vc.view];
                [[UIApplication sharedApplication].keyWindow.rootViewController addChildViewController:vc];
            }
        }];
        [[UIApplication sharedApplication].keyWindow addSubview:_bottomView];
        
        CGFloat height = 0;
        if (@available(iOS 13.0, *)) {
            NSSet *set = [UIApplication sharedApplication].connectedScenes;
            UIWindowScene *windowScene = [set anyObject];
            UIWindow *window = windowScene.windows.firstObject;
            height = window.safeAreaInsets.bottom;
        } else if (@available(iOS 11.0, *)) {
            UIWindow *window = [UIApplication sharedApplication].windows.firstObject;
            height = window.safeAreaInsets.bottom;
        }
        height += 49;

        
        [_bottomView mas_makeConstraints:^(MASConstraintMaker *make) {
            make.left.right.equalTo([UIApplication sharedApplication].keyWindow);
            make.bottom.equalTo([UIApplication sharedApplication].keyWindow).offset(-height);
            make.height.mas_equalTo(60);
        }];
    }
    return _bottomView;
}


- (UIImageView *)iconImage {
    if (!_iconImage) {
        _iconImage = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT)];
        _iconImage.contentMode = UIViewContentModeScaleAspectFit;
    }
    return _iconImage;
}
@end
